perm filename GRNFAI.FAI[S,HE] blob sn#556855 filedate 1981-01-22 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00004 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002		TITLE	GRNFAI
C00003 00003	 The MAXPACK stuff was discarded since it was a hardware thing anyway.
C00006 00004	AC's
C00012 ENDMK
C⊗;
	TITLE	GRNFAI
	SUBTTL	MAY 29 '80	ALLAN MILLER
	SEARCH	GRNDEF (GRNDEF.FUN[HDR,HE])
	SEARCH	PIXDEF (PIXDEF.FUN[HDR,HE])
	EXTERN	GRNINS
	ENTRY	OUTLIN

;This is for Grinnell stuff that ran too slow in SAIL.  Original SAIL code included
;  as comments.

;SAIL stuff
P←17
RETAD:	BLOCK	1		;Who called us
; The MAXPACK stuff was discarded since it was a hardware thing anyway.
; Another argument was added, so that bytes could be shifted before output.
COMMENT⊗
PACKOUT outputs a line of image data to the Grinnell.

PROCEDURE PACKOUT(REFERENCE INTEGER PTR; INTEGER LINELEN);
Comment PACKOUT outputs a line to the Grinnell in byte-packed format.
	PTR - byte pointer to line so far (is changed by ILDB)
	LINELEN - how many bytes to output (MAXPACK is maximum);

BEGIN "PACKOUT"
INTEGER I;		Comment temp;
INTEGER B1,B2;		Comment Data bytes output;

   GRNINS(SPD LOR BYTEUNPACK);	Comment Set up data packing;
   GRNINS(LPR LOR BYTEIMAGE LOR (TRUNC*(LINELEN MOD 2))
			LOR (((LINELEN+1) DIV 2) MOD (MAXPACK DIV 2)) );
			Comment 0 len means max;
   FOR I ← 1 STEP 2 UNTIL LINELEN DO
      BEGIN
	B1 ← ILDB(PTR);
	B2 ← ILDB(PTR);
	GRNINS((B1 LSH 8) LOR B2)
      END;
   IF (LINELEN MOD 2) ≠ 0 THEN GRNINS(ILDB(PTR) LSH 8)
END "PACKOUT";

PROCEDURE OUTLINE(INTEGER ARRAY PIC; INTEGER LINE);
Comment OUTLINE outputs one line of a picture to the Grinnell.
	PIC - the picture
	LINE - the number of the line to output;
BEGIN "OUTLINE"
INTEGER PTR,LINELEN;		Comment byte pointer and line length;

Comment if the number of bits in the picture is 8 or less, use packed-mode output;

   LINELEN ← PIC[LNBY];
   PTR ← MEMORY[PIC[BPTAB]-1,INTEGER] + PIC[LINTAB+LINE-1]; Comment get byte ptr;
   IF PIC[BYBI] ≤ 8 THEN

	Comment can only put out MAXPACK packed pixels at a time;
	WHILE LINELEN > 0 DO
	   BEGIN
	      PACKOUT(PTR,MAXPACK MIN LINELEN);
	      LINELEN ← LINELEN - MAXPACK
	   END
   ELSE

	Comment just use WID instructions;
	WHILE LINELEN > 0 DO
	   BEGIN
	      GRNINS(WID LOR ILDB(PTR));
	      LINELEN ← LINELEN - 1
	   END
END "OUTLINE";
⊗
;AC's
PIC←1;
T1←2;
T2←3;

;Storage
PTR:	BLOCK	1		;Byte pointer to fetch line
LINELN:	BLOCK	1		;Length of line, in bytes
OUTLEN:	BLOCK	1		;Number of bytes going out now (packed mode)
SHFTBY: BLOCK   1		;Right half of shift amount (for indirect addr)
SHFAMT:	BLOCK	1		;Unmodified shift amount

OUTLIN:	POP	P,RETAD		;Get arguments
	POP	P,T1
	MOVEM	T1,SHFAMT
	HRRZM	T1,SHFTBY	;only save right half (for LSH instr)
	POP	P,T1		;This is line no., use it to get byte ptr to line
	POP	P,PIC

; Get line length and pointer to line

	MOVE	T2,BPTAB(PIC)	;Get addr of byte pointer table
	MOVE	T2,-1(T2)	;Fetch byte pointer just in front of table
	ADD	T1,PIC
	ADD	T2,LINTAB(T1)	;Add address of line to byte pointer
	MOVEM	T2,PTR

	MOVE	T1,LNBY(PIC)
	MOVEM	T1,LINELN


; ****  TEST TO SEE IF PACKED MODE HAS BEEN FIXED ************************
; Since at the time of this writting the Grinnell fails on packed
; mode a flag defined in GRNDEF[HDR,AAM] indicates the current status
; This should be deleted once the Grinnell has been repaired
	SKIPN	[PACKOK]
	JRST	UNPAK
; *+*+*+*+*+*+*+*+*++*++*++*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+

; If 8-bit picture or less, use packed mode otherwise unpacked
;  but only use unpacked for larger if not shifted down to 8 bits or less
	MOVE	T1,BYBI(PIC)
	ADD	T1,SHFAMT
	CAILE	T1,=8
	 JRST	UNPAK
	

; Unpacked mode.  Do a SPD BYTEUNPACK.

	MOVEI	T1,SPD!BYTEUN
	PUSH	P,T1
	PUSHJ	P,GRNINS	;THIS INVALIDATES CONTENTS OF ACS!!!

; Now an LPR.  The TRUNC bit is only turned on if the linelength is odd.  The
;   maximum number of words that can go out is 256.  256→0.

LPRINS:	MOVE	T2,LINELN
	CAILE	T2,=512	;Trying to put out more than 512 bytes?
	 MOVEI	T2,=512	; Yes.  Can only put out 512
	MOVEM	T2,OUTLEN	;Save as number of bytes going out.

	MOVEI	T1,LPR!BYTEIM	;Image data
	TRNE	T2,1		;If length out is odd,
	 TRO	T1,TRUNC	; truncate last byte on output
	ADDI	T2,1		;Words out = ceil(outlen/2)
	LSH	T2,-1
	ANDI	T2,377		;No. words must fit in 8 bits (0 means 256)
	IOR	T1,T2
	PUSH	P,T1
	PUSHJ	P,GRNINS

; Here is the "speedy" inner loop...fancy stuff to take care of odd line lengths

PIXEL:	ILDB	T1,PTR		;Get first byte
	LSH	T1,@SHFTBY	;Shift it if desired
	LSH	T1,=8
	SOSG	OUTLEN		;More bytes left?
	 JRST	NOMORE		;  no...leave last one as 0.
	ILDB	T2,PTR		;Get second byte
	LSH	T2,@SHFTBY	;And shift it too
NOMORE:	IOR	T1,T2
	PUSH	P,T1
	PUSHJ	P,GRNINS
	SOSLE	OUTLEN		;More bytes left?
	 JRST	PIXEL		;  yes...continue

	MOVE	T1,LINELN	;Take off max. bytes that could have gone out.
	SUBI	T1,=512
	MOVEM	T1,LINELN
	JUMPG	T1,LPRINS	;If more to output, go do it

	JRST	@RETAD		;Otherwise return

;Unpacked mode output is real easy.  Just do a bunch of WIDs.
UNPAK: 	

;I didn't put this code in, so when I made "shiftby" an argument, I took it out.
;	SETZM	SHFTBY		;Initialize shift count to zero
;	MOVN	T2,BYBI(PIC)	;Get negative of the number of bits per pixel
;	ADDI	T2,=8		;add max bits available on the grinnel to get shift
;	SKIPGE	T2		;if less than 8 bytes we don't want to shift
;	HRRZM   T2,SHFTBY	;save the shift count in right half

UPLOOP:	ILDB	T1,PTR
	LSH	T1,@SHFTBY	;shift pixel if desired
	IORI	T1,WID
	PUSH	P,T1
	PUSHJ	P,GRNINS
	SOSLE	LINELN
	JRST	UPLOOP

	JRST	@RETAD

	END